package com.mine.frame.common.custom

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.mine.frame.common.R
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt

/**
 * company 广东玛格家居有限公司
 * @author smoker
 * @Date 2021/12/13
 * Description:线波语音视图
 */
class LineWaveVoiceView : View {

    private lateinit var disposable: Disposable

    //当前音量大小
    private var volume = 0
    private val paint: Paint by lazy { Paint() }

    //矩形波纹宽度
    private var lineWidth = 0f

    private var isStart = false


    private val mWaveList = LinkedList<Int>()

    private val rectRight by lazy { RectF() }  //右边波纹矩形的数据，10个矩形复用一个rectF

    private val rectLeft by lazy { RectF() } //左边波纹矩形的数据

    private var list = LinkedList<Int>()

    private var intervalWidth = 0f //两个波形之间的间隔

    //每个音量的颜色
    private val colorList = intArrayOf(
        Color.parseColor("#b0007a"),
        Color.parseColor("#b0007a"),
        Color.parseColor("#b0007a"),
        Color.parseColor("#b0007a"),
        Color.parseColor("#b0007a"),
        Color.parseColor("#a7007b"),
        Color.parseColor("#8f007b"),
        Color.parseColor("#72007d"),
        Color.parseColor("#5b007e"),
        Color.parseColor("#47007f"),
        Color.parseColor("#3c0081"),
        Color.parseColor("#350082"),
        Color.parseColor("#330086"),
        Color.parseColor("#30008b"),
        Color.parseColor("#2b0192"),
        Color.parseColor("#28099e"),
        Color.parseColor("#2312aa"),
        Color.parseColor("#201bb6"),
        Color.parseColor("#1e1eba"),
        Color.parseColor("#1e1eba"),
        Color.parseColor("#1e1eba")
    )

    companion object {
        //默认矩形波纹的高度，总共10个矩形，左右各有10个
        private val DEFAULT_WAVE_HEIGHT = intArrayOf(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)

        private const val INTERVAL_W = 60 //两边波纹之间的间隔

        private const val LINE_W = 9 //默认矩形波纹的宽度，9像素, 原则上从layout的attr获得

        private const val MIN_WAVE_H = 1 //最小的矩形线高，是线宽的2倍，线宽从lineWidth获得

        private const val MAX_WAVE_H = 40 //最高波峰，是线宽的4倍

        private const val UPDATE_INTERVAL_TIME = 100L //100ms更新一次

    }

    constructor(context: Context) : super(context)

    constructor(context: Context, attr: AttributeSet) : this(context, attr, 0)

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        resetList(list, DEFAULT_WAVE_HEIGHT)
        val mTypedArray: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.LineWaveVoiceView)
        lineWidth = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_voiceLineWidth, LINE_W.toFloat())
        intervalWidth = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_intervalWidth, INTERVAL_W.toFloat())
        mTypedArray.recycle()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        val widthcentre = width / 2
        val heightcentre = height / 2

        //更新时间
        paint.strokeWidth = 0f
        //更新左右两边的波纹矩形
        paint.style = Paint.Style.FILL
        paint.strokeWidth = lineWidth
        paint.isAntiAlias = true
        for (i in DEFAULT_WAVE_HEIGHT.indices) {
            paint.color = colorList[i]

            //右边矩形
            rectRight.left = widthcentre + 2 * i * lineWidth + intervalWidth / 2 + lineWidth
            rectRight.top = heightcentre - list[i] * lineWidth
            rectRight.right = widthcentre + 2 * i * lineWidth + 2 * lineWidth + intervalWidth / 2
            rectRight.bottom = heightcentre + list[i] * lineWidth

            //左边矩形
            rectLeft.left = widthcentre - (2 * i * lineWidth + intervalWidth / 2 + 2 * lineWidth)
            rectLeft.top = heightcentre - list[i] * lineWidth
            rectLeft.right = widthcentre - (2 * i * lineWidth + intervalWidth / 2 + lineWidth)
            rectLeft.bottom = heightcentre + list[i] * lineWidth
            canvas?.drawRoundRect(rectRight, 6f, 6f, paint)
            canvas?.drawRoundRect(rectLeft, 6f, 6f, paint)
        }

    }

    /**
     * 设置当前音量
     */
    fun setVolume(volume: Int) {
        this.volume = volume
    }


    @Synchronized
    fun startRecord() {
        isStart = true
        openTime()
    }

    @Synchronized
    fun stopRecord() {
        isStart = false
        stopTime()
        mWaveList.clear()
        resetList(list, DEFAULT_WAVE_HEIGHT)
        postInvalidate()
    }


    private fun resetList(list: LinkedList<Int>, array: IntArray) {
        list.clear()
        for (value in array) {
            list.add(value)
        }
    }


    private fun openTime() {
        Observable.interval(UPDATE_INTERVAL_TIME, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { disposable -> this.disposable = disposable }
            .doOnNext {
                if (isStart) {
                    refreshElement()
                    postInvalidate()
                }
            }
            .subscribe()
    }

    private fun stopTime() {
        if (this::disposable.isInitialized && !disposable.isDisposed) {
            disposable.dispose()
        }
    }


    @Synchronized
    private fun refreshElement() {
        val maxAmp = volume * 1.0f / 100
        val waveH = MIN_WAVE_H + (maxAmp * (MAX_WAVE_H - 2)).roundToInt()
        list.add(0, waveH)
        list.removeLast()
    }


}